package com.abc.pay.client;

import com.kxmall.common.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.httpclient.HttpClient;
//import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
//import org.apache.commons.httpclient.methods.PostMethod;
import java.io.*;
//import java.net.ConnectException;
//import java.net.UnknownHostException;
//import java.nio.charset.StandardCharsets;

@Slf4j
public abstract class TrxRequest {
    private String iECMerchantType;
    public boolean connectionFlag = false;
    private MerchantPara para = null;
    private String tRequestMesg = "";

    public TrxRequest(String aECMerchantType) {
        this.iECMerchantType = aECMerchantType;

        try {
            this.para = MerchantConfig.getUniqueInstance().getPara();
        } catch (TrxException trxException) {
            log.error(Util.getExceptionString(trxException));
            trxException.printStackTrace();
        }

    }

    public JSON postRequest() {
        return this.extendPostRequest(1);
    }

    public JSON extendPostRequest(int i) {
        String responseMessage;
        JSON json;
        SignService sign;

        try {
            log.info("TrustPayClient Java V3.2.2 交易开始==========================");
            String requestMessage = this.getRequestMessage();
            requestMessage = this.composeRequestMessage(i, requestMessage);
            sign = SignService.getUniqueInstance();
            requestMessage = sign.signMessage(i, requestMessage);
            responseMessage = this.sendMessage(requestMessage);
            responseMessage = responseMessage.substring(responseMessage.indexOf("{\"MSG"));
            json = new JSON(responseMessage);
            log.info("验证线上支付平台响应报文的签名：");
            log.info("正确");
        } catch (TrxException trxException) {
            log.error("错误代码：[" + trxException.getCode() + "], 错误信息：[" + trxException.getMessage() + "," + trxException.getDetailMessage() + "]");
            responseMessage = "{\"ReturnCode\":\"" + trxException.getCode() + "\";\"ErrorMessage\":\"" + trxException.getDetailMessage() + "\"}";
            json = new JSON(responseMessage);
            json.setJsonString(responseMessage);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("错误代码：[系统发生无法预期的错误]    错误信息：[" + e.getMessage() + "]");
            responseMessage = "{\"ReturnCode\":\"1999\";\"ErrorMessage\":\"系统发生无法预期的错误 - " + e.getMessage() + "\"}";
            json = new JSON(responseMessage);
            json.setJsonString(responseMessage);
        } finally {
            log.info("交易结束==================================================");
        }
        log.info(responseMessage);
        return json;
    }

    public String genSignature(int i) throws TrxException {
        SignService sign;

        try {
            log.info("TrustPayClient Java V3.2.2 交易开始==========================");
            log.info("检查交易请求是否合法：");
            this.checkRequest();
            log.info("正确");
            log.info("交易报文：");
            String tRequestMessage = this.getRequestMessage();
            log.info(tRequestMessage);
            log.info("完整交易报文：");
            tRequestMessage = this.composeRequestMessage(i, tRequestMessage);
            log.info(tRequestMessage);
            log.info("签名后的报文：");
            sign = SignService.getUniqueInstance();
            tRequestMessage = sign.signMessage(i, tRequestMessage);
            StringBuffer tTempStringBuffer = (new StringBuffer()).append(tRequestMessage);
            this.tRequestMesg = tTempStringBuffer.toString();
            log.info(this.tRequestMesg);
            this.tRequestMesg = this.tRequestMesg.replace("\"", "&quot;");
            log.info("提交线上支付平台的报文：\n" + this.tRequestMesg);
        } catch (TrxException trxException) {
            log.error("错误代码：[" + trxException.getCode() + "]    错误信息：[" + trxException.getMessage() + " - " + trxException.getDetailMessage() + "]");
            throw new TrxException(trxException.getCode(), trxException.getMessage() + " - " + trxException.getDetailMessage());
        } catch (Exception e) {
            log.error("错误代码：[1999]    错误信息：[系统发生无法预期的错误 - " + e.getMessage() + "]");
            throw new TrxException("1999", "系统发生无法预期的错误 - " + e.getMessage());
        } finally {
            log.info("交易结束==================================================");
        }
        return this.tRequestMesg;
    }

    protected abstract void checkRequest() throws TrxException;

    protected abstract String getRequestMessage() throws TrxException;

    private String composeRequestMessage(int i, String inputMessage) throws TrxException {
        String message = "{\"Version\":\"V3.0.0\",\"Format\":\"JSON\",\"Merchant\":{\"ECMerchantType\":\"" + this.iECMerchantType + "\",\"MerchantID\":\"" + this.para.getMerchantID(i) + "\"},\"TrxRequest\":{" + inputMessage.substring(1) + "}}";
        log.info(message);
        return message;
    }

    private String sendMessage(String inputRequest) throws TrxException {
        log.info("准备提交线上支付平台请求报文：\n" + inputRequest);
        int port = Integer.parseInt(this.para.getTrustPayServerPort());
        //int trustPayServerTimeout = this.getTrustPayServerTimeout(this.para.getTrustPayServerTimeout());
        //String proxyIP = this.para.getProxyIP();
        //String proxyPort = this.para.getProxyPort();
        String connectMethod = this.para.getTrustPayConnectMethod();
        String url = String.format("%s://%s%s%s", connectMethod, this.para.getTrustPayServerName(), "443".equals(Integer.toString(port)) ? "" : ":" + port, !inputRequest.contains("DownloadStatement") ? this.para.getTrustPayTrxURL() : this.para.getTrustPayFileTrxURL());
        String responseMessage = HttpClientUtils.doPostStr(url, inputRequest);
        log.info("解析返回报文成功，HTTP返回报文：\n" + responseMessage);
        if (!responseMessage.contains("MSG")) {
            throw new TrxException("1205", "无法辨识线上支付平台的响应报文");
        }
//        PostMethod post = null;
//        try {
//            HttpClient client = new HttpClient();
//            client.getHttpConnectionManager().getParams().setSoTimeout(trustPayServerTimeout);
//            client.getHttpConnectionManager().getParams().setConnectionTimeout(trustPayServerTimeout);
//            if (!proxyIP.equals("") && !proxyPort.equals("")) {
//                client.getHostConfiguration().setProxy(proxyIP, Integer.parseInt(proxyPort));
//            }
//            client.getHttpConnectionManager().getParams().setTcpNoDelay(true);
//            client.getHttpConnectionManager().getParams().setStaleCheckingEnabled(false);
//            log.info("请求服务器地址:" + url);
//            post = new PostMethod(url);
//            post.getParams().setCookiePolicy("ignoreCookies");
//            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(inputRequest.getBytes(StandardCharsets.UTF_8));
//            post.setRequestEntity(new InputStreamRequestEntity(byteArrayInputStream));
//            post.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
//            int result = client.executeMethod(post);
//            log.info("发送请求报文：成功");
//            responseMessage = this.getResponse(post.getResponseBodyAsStream());
//            log.info("解析返回报文成功，HTTP返回报文：\n" + responseMessage);
//            if (!responseMessage.contains("MSG")) {
//                throw new TrxException("1205", "无法辨识线上支付平台的响应报文");
//            }
//            if (result < 200 || result >= 400) {
//                throw new TrxException("1206", "线上支付平台服务暂时停止");
//            }
//        } catch (TrxException trxException) {
//            log.error(Util.getExceptionString(trxException));
//            log.error("[HTTPClient] - 发送交易报文失败:" + trxException.getMessage());
//            throw trxException;
//        } catch (UnknownHostException unknownHostException) {
//            log.error(Util.getExceptionString(unknownHostException));
//            log.error("[HTTPClient] - 发送交易报文失败:" + unknownHostException.getMessage());
//            throw new TrxException("1201", "无法连线线上支付平台", "无法取得[" + this.para.getTrustPayServerName() + "]的IP地址!");
//        } catch (ConnectException connectException) {
//            log.error(Util.getExceptionString(connectException));
//            log.error("[HTTPClient] - 发送交易报文失败:" + connectException.getMessage());
//            throw new TrxException("1201", "无法连线线上支付平台", "无法连线" + this.para.getTrustPayServerName() + "的" + this.para.getTrustPayServerPort() + "端口!");
//        } catch (Exception socketException) {
//            log.error(Util.getExceptionString(socketException));
//            log.error("[HTTPClient] - 发送交易报文失败:" + socketException.getMessage());
//            throw new TrxException("1202", "提交交易时发生网络错误", "连线中断！");
//        } finally {
//            if (post != null) {
//                post.releaseConnection();
//            }
//        }
        return responseMessage;
    }

    private int getTrustPayServerTimeout(String trustPayServerTimeout) throws TrxException {
        try {
            return "".equals(trustPayServerTimeout) ? 300000 : Integer.parseInt(this.para.getTrustPayServerTimeout());
        } catch (NumberFormatException e) {
            log.error(Util.getExceptionString(e));
            throw new TrxException("1001", "商户端配置文件中参数设置错误", "无法读取超时时间");
        }
    }

    private String getResponse(InputStream responseStream) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(responseStream, "GBK"));
        StringBuffer stringBuffer = new StringBuffer();
        String line;

        while((line = br.readLine()) != null) {
            stringBuffer.append(line);
        }

        return stringBuffer.toString();
    }
}

